﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Common.Utilities;
using Common.Utilities.Database;
using Common.Utilities.Dispatcher;

namespace Workflows.Components.Entities.MasterData
{
    public partial class DbProfileEditor : Form, IComponentEditor
    {
        private object _ActivityNode;
        private DbProfileComponent _Profiler;

        public DbProfileEditor()
        {
            InitializeComponent();
        }

        private void DbProfileEditor_Load(object sender, EventArgs e)
        {
            this.cbo_DbServers.Items.Clear();
            string[] dbServers = SqlServerEnumUtil.GetAvailableServers();
            if (dbServers != null && dbServers.Length > 0)
            {
                foreach (string dbServer in dbServers)
                {
                    this.cbo_DbServers.Items.Add(dbServer);
                }
            }
        }

        private void btn_OK_Click(object sender, EventArgs e)
        {
            this.SaveSettings();
            if (this.UpdateComponentSettingEvent != null)
                this.UpdateComponentSettingEvent(this._ActivityNode, this._Profiler);
            this.Close();
        }

        private void btn_Cancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void cbo_DbServers_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_DbServers.SelectedIndex>=0)
            {
                string connStr = string.Format("Data source={0};database=master;integrated security=sspi;",this.cbo_DbServers.Text);
                if(this.ck_IntegratedSecurity.Checked == false)
                {
                    connStr = string.Format("Data source={0};database=Master;User ID={1};Password={2}",
                                            this.cbo_DbServers.Text, this.txt_UserID.Text, this.txt_Password.Text);
                }
                string[] dbNames = DbUtil.GetDatabases(connStr);
                this.cbo_Dbs.Items.Clear();
                if(dbNames !=null && dbNames.Length>0)
                {
                    foreach (string dbName in dbNames)
                        this.cbo_Dbs.Items.Add(dbName);
                }
            }

        }

        private void cbo_Dbs_SelectedIndexChanged(object sender, EventArgs e)
        {
            if(this.cbo_Dbs.SelectedIndex>=0 && this.cbo_DbServers.SelectedIndex>=0)
            {
                string connStr = string.Format("Server={0};Database={1};Integrated Security=SSPI;",
                                               this.cbo_DbServers.Text, this.cbo_Dbs.Text);
                if (!this.ck_IntegratedSecurity.Checked)
                    connStr = string.Format(
                        "Server={0};Database={1};User ID={2};Password={3}",
                        this.cbo_DbServers.Text, this.cbo_Dbs.Text, this.txt_UserID.Text,
                        this.txt_Password.Text);
                Dictionary<string, List<string>> tblsBySchemas = DbUtil.GetTableNamesWithSchemas(
                    DataProviderType.MSSQL, connStr);
                this.clb_Tables.Items.Clear();
                if(tblsBySchemas !=null && tblsBySchemas.Count>0)
                {
                    foreach(string schemaName in tblsBySchemas.Keys)
                    {
                        foreach(string tblName in tblsBySchemas[schemaName])
                        {
                            this.clb_Tables.Items.Add(schemaName + "." + tblName);
                        }
                    }
                }
            }
        }

        #region Implementation of IComponentEditor

        public event UpdateComponentSettings UpdateComponentSettingEvent;

        /// <summary></summary>
        public object OwnerActivityNode
        {
            get
            {
                return _ActivityNode;
            }
            set
            {
                _ActivityNode = value;
            }
        }

        /// <summary></summary>
        public Type WorkflowComponentType
        {
            get
            {
                return typeof(DbProfileComponent);
            }
        }

        /// <summary></summary>
        public void LoadSettings(GlobalVariable[] globalVars, WorkflowComponentBase[] fromComponents, object activityNode, WorkflowComponentBase wfComponent)
        {
            this._ActivityNode = activityNode;
            this._Profiler = (DbProfileComponent)wfComponent;

            DbProfileInstruction instruction =
                (DbProfileInstruction)this._Profiler.Instruction;

            this._Profiler.Instruction = instruction;
            this.txt_UserID.Text = instruction.DbUserName;
            this.txt_Password.Text = instruction.DbPassword;
            this.ck_IntegratedSecurity.Checked = instruction.IntegratedSecurity;
            this.SelectComboboxItem(this.cbo_DbServers, instruction.DataSourceName);
            this.SelectComboboxItem(this.cbo_Dbs, instruction.DbName);

            List<string> schemaTblNames = new List<string>();
            if (instruction.TablesBySchemas != null && instruction.TablesBySchemas.Count > 0)
            {
                foreach (string schemaName in instruction.TablesBySchemas.Keys)
                {
                    foreach (string tblname in instruction.TablesBySchemas[schemaName])
                    {
                        schemaTblNames.Add(schemaName + "." + tblname);
                    }
                }
            }
            if (this.clb_Tables.Items.Count > 0)
            {
                for (int i = 0; i < this.clb_Tables.Items.Count; i++)
                {
                    if (schemaTblNames.Contains(this.clb_Tables.Items[i].ToString()))
                        this.clb_Tables.SetItemChecked(i, true);
                    else
                        this.clb_Tables.SetItemChecked(i, false);
                }
            }
            this.ck_IndexedColumnsOnly.Checked = instruction.ProfileIndexedColumnsOnly;
            this.txt_OutputFilePath.Text = instruction.OutputFilePath;
        }

        /// <summary></summary>
        public void SaveSettings()
        {
            DbProfileInstruction instruction =
               (DbProfileInstruction)this._Profiler.Instruction;

            instruction.DataSourceName = this.cbo_DbServers.Text;
            instruction.DbName = this.cbo_Dbs.Text;
            instruction.IntegratedSecurity = this.ck_IntegratedSecurity.Checked;
            if(this.ck_IntegratedSecurity.Checked)
            {
                instruction.DbUserName = string.Empty;
                instruction.DbPassword = string.Empty;
            }
            else
            {
                instruction.DbUserName = this.txt_UserID.Text;
                instruction.DbPassword = this.txt_Password.Text;
            }
            instruction.ProfileIndexedColumnsOnly = this.ck_IndexedColumnsOnly.Checked;
            instruction.OutputFilePath = this.txt_OutputFilePath.Text;
            instruction.TablesBySchemas=new Dictionary<string, List<string>>();
            for(int i=0;i<this.clb_Tables.Items.Count;i++)
            {
                if(this.clb_Tables.GetItemChecked(i))
                {
                    string schemaTable = this.clb_Tables.Items[i].ToString();
                    string[] parts = schemaTable.Split(new char[] {'.'});
                    string schemaName = parts[0];
                    string tblName = parts[1];
                    if(instruction.TablesBySchemas.ContainsKey(schemaName))
                    {
                        List<string> tblNames = instruction.TablesBySchemas[schemaName];
                        tblNames.Add(tblName);
                        instruction.TablesBySchemas[schemaName] = tblNames;
                    }
                    else
                    {
                        List<string> tblNames=new List<string>();
                        tblNames.Add(tblName);
                        instruction.TablesBySchemas.Add(schemaName, tblNames);
                    }
                }
            }

            this._Profiler.Instruction = instruction;
        }

        /// <summary></summary>
        public TestResult Test()
        {
            throw new System.NotImplementedException();
        }

        #endregion

        private void SelectComboboxItem(ComboBox comboBox, string value)
        {
            if(!string.IsNullOrEmpty(value) && comboBox.Items.Count>0)
            {
                for(int i=0;i<comboBox.Items.Count;i++)
                {
                    if(comboBox.Items[i].ToString()==value)
                    {
                        comboBox.SelectedIndex = i;
                        break;
                    }
                }
            }
        }

        private void btn_SaveAs_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg=new SaveFileDialog();
            dlg.Filter = "Excel files(*.xlsx)|*.xlsx|Profile files(*.prof)|*.prof|All files(*.*)|*.*";
            if(dlg.ShowDialog()==DialogResult.OK)
                this.txt_OutputFilePath.Text = dlg.FileName;
        }

        private void btn_SelectAllTables_Click(object sender, EventArgs e)
        {
            for(int i=0;i<this.clb_Tables.Items.Count;i++)
            {
                this.clb_Tables.SetItemChecked(i,true);
            }
        }

        private void btn_OpenResult_Click(object sender, EventArgs e)
        {
            TableFieldProfileViewer profileViewer=new TableFieldProfileViewer();
            profileViewer.Show();
        }
    }
}
